<?php

namespace App\Api\Traits\Orm;

use Illuminate\Database\Eloquent\Model;

trait SearchTrait
{

    //查询字段配置(示例)

    // private $search_params = [
    //      ['where', 'vip_level', '>' ,4], //会员等级大于4
    //      ['where', 'nick', 'like', '$params-one'], // 昵称模糊匹配$params-one
    //      ['whereIn', 'id', '$params-two'], // id在$params-two中
    //      ['orderBy', 'vip_level', 'asc'] // 按从小到大的等排序
    // ];

    //后续操作配置
    //private $format_operations = [
    //   'params-one' => '%$params-one%', // 将$params中的params-one参数格式化为 '%'.$params['params-one'].'%'
    //   'params-two' => function ($param) {
    //        return explode(',', $param); // 将$params中的params-two参数用逗号分割成一个数组
    //   },
    //]

    public function searchV2($params, $search_params = null, $format_operations = null, $type = 0)
    {
        if ($search_params === null) {
            $search_params = $this->search_params ?? [];
        }
        if ($format_operations === null) {
            $format_operations = $this->format_operations ?? [];
        }
        $sql = $this;
        $result = ['total' => 0, 'rows' => []];

        foreach ($search_params as $judgment) {
            $func = $judgment[0];
            unset($judgment[0]);
            $func_params = [];
            foreach ($judgment as $param) {
                if (gettype($param) === 'string') {
                    //使用了变量，那么变量存在就生效，不存在就不算入查询条件
                    if (substr($param, 0, 1) === '$') {
                        if (isset($params[substr($param, 1)])) {
                            $field = substr($param, 1);
                            // 使用了格式化操作就调用格式化操作
                            if (isset($format_operations[$field])) {
                                $format_type = gettype($format_operations[$field]);
                                // 格式化操作是一个方法，就调用这个方法
                                if ($format_type === 'object') {
                                    $format_func = $format_operations[$field];
                                    $func_params[] = call_user_func($format_func, $params[$field]);
                                }
                                // 格式化操作是一个串就按串的解析
                                if ($format_type === 'string') {
                                    $func_params[] = str_replace($param, $params[$field], $format_operations[$field]);
                                }

                            } else {
                                $func_params[] = $params[substr($param, 1)];
                            }
                        } else {
                            $func_params = [];
                            continue;
                        }
                    } else { // 使用常量字符串
                        $func_params[] = $param;
                    }
                } else { // 使用了其他常量
                    $func_params[] = $param;
                }
            }
            switch (count($func_params)) {
                case 1:
                {
                    $sql = $sql->$func($func_params[0]);
                    break;
                }
                case 2:
                {
                    $sql = $sql->$func($func_params[0], $func_params[1]);
                    break;
                }
                case 3:
                {
                    $sql = $sql->$func($func_params[0], $func_params[1], $func_params[2]);
                    break;
                }
                case 4:
                {
                    $sql = $sql->$func($func_params[0], $func_params[1], $func_params[2], $func_params[3]);
                    break;
                }
                default:
                {
                    break;
                }
            }
        }
        $result['total'] = $sql->count();
        if ($result['total'] > 0) {
            // 如果type不为空则取出结果做复杂查询
            if ($type) {
                return $sql;
            }
            $result['rows'] = $sql->skip($params['offset'])->take($params['limit'])->get();
        }
        return $result;
    }

    /**
     * @exp 分页
     * @param array $params //获取偏移量limit与offset数组 与排序列表
     * @param mixed $sql 查询orm
     * @param array $select // 模糊查询的字段
     * @return array|bool
     */
    public function page(array $params, mixed $sql, array $select = []): array|bool
    {
        if ($select && isset($params['select'])) { // 模糊查询字段
            $sql = $sql->likeSearch($select, $params['select']);
        }
        if (isset($params['orderBy']) && is_array($params['orderBy'])) {
            foreach ($params['orderBy'] as $key => $val) {
                $sql = $sql->orderBy($key, $val); // key:$column val:asc/desc
            }
        } else {
            $sql->latest();
        }
        $res['total'] = $sql->count();
        if ($res['total']) {
            if (isset($params['limit']) && isset($params['offset'])) {
                $res['rows'] = $sql->limit($params['limit'])->offset($params['offset'])->get();
            } else {
                $res['rows'] = $sql->get();
            }
            return $res;
        } else {
            return false;
        }
    }
}
